////
////  FFTProcessor.swift
////  AnyAudio
////
////  Created by hq_ly on 2025/7/1.
////
//
//
//import SwiftUI
//import AVFoundation
//import Accelerate
//import Combine
//import CoreGraphics
//
//// MARK: - 音频处理核心
//
///// FFT处理器
//class FFTProcessor {
//    static let windowSize = 2048
//    static let hopSize = 512
//    
//    private(set) var fftSetup: vDSP.FFT<DSPSplitComplex>?
//    private(set) var forwardInputBuffer: [Float]
//    private(set) var forwardOutputReal: [Float]
//    private(set) var forwardOutputImag: [Float]
//    private let hanningWindow: [Float]
//    
//    init() {
//        self.forwardInputBuffer = [Float](repeating: 0, count: Self.windowSize)
//        self.forwardOutputReal = [Float](repeating: 0, count: Self.windowSize)
//        self.forwardOutputImag = [Float](repeating: 0, count: Self.windowSize)
//        
//        // 正确创建汉宁窗
//        var window = [Float](repeating: 0, count: Self.windowSize)
//        vDSP_hann_window(&window, vDSP_Length(Self.windowSize), Int32(0))
//        self.hanningWindow = window
//        
//        let log2n = vDSP_Length(log2(Float(Self.windowSize)))
//        self.fftSetup = vDSP.FFT(
//            log2n: log2n,
//            radix: .radix2,
//            ofType: DSPSplitComplex.self
//        )!
//    }
//    
//    /// 执行FFT分析
//    func process(_ buffer: AVAudioPCMBuffer) -> [[Float]] {
//        guard let floatData = buffer.floatChannelData?[0] else { return [] }
//        let frameCount = Int(buffer.frameLength)
//        
//        var results: [[Float]] = []
//        
//        for i in stride(from: 0, to: frameCount, by: FFTProcessor.hopSize) {
//            let endIndex = min(i + FFTProcessor.windowSize, frameCount)
//            let length = endIndex - i
//            
//            // 应用汉宁窗
//            var windowed = [Float](repeating: 0, count: FFTProcessor.windowSize)
//            applyHanningWindow(input: floatData, start: i, length: length, output: &windowed)
//            
//            // 执行FFT
//            performFFT(on: windowed)
//            
//            // 计算幅度谱 (只取前一半)
//            var magnitudes = [Float](repeating: 0, count: FFTProcessor.windowSize / 2)
//            computeMagnitudes(output: &magnitudes)
//            
//            // 保存结果
//            results.append(magnitudes)
//        }
//        
//        return results
//    }
//    
//    /// 应用汉宁窗
//    private func applyHanningWindow(input: UnsafePointer<Float>, start: Int, length: Int, output: inout [Float]) {
//        output.withUnsafeMutableBufferPointer { outputPtr in
//            // 复制数据并应用窗函数
//            vDSP_vmul(input.advanced(by: start), 1, 
//                      hanningWindow, 1, 
//                      outputPtr.baseAddress!, 1, 
//                      vDSP_Length(length))
//            
//            // 用零填充剩余部分
//            if length < FFTProcessor.windowSize {
//                for i in length..<FFTProcessor.windowSize {
//                    outputPtr[i] = 0
//                }
//            }
//        }
//    }
//    
//    /// 执行FFT
//    private func performFFT(on input: [Float]) {
//        forwardInputBuffer = input
//        
//        // 准备输入复数格式 (虚部全为0)
//        var realBuffer = forwardInputBuffer
//        var imagBuffer = [Float](repeating: 0, count: forwardInputBuffer.count)
//        
//        var inputSplitComplex = DSPSplitComplex(
//            realp: &realBuffer,
//            imagp: &imagBuffer
//        )
//        
//        // 准备输出缓冲区
//        var outputSplitComplex = DSPSplitComplex(
//            realp: &forwardOutputReal,
//            imagp: &forwardOutputImag
//        )
//        
//        // 执行FFT
//        fftSetup?.forward(input: inputSplitComplex, output: &outputSplitComplex)
//    }
//    
//    /// 计算幅度
//    private func computeMagnitudes(output: inout [Float]) {
//        for i in 0..<FFTProcessor.windowSize / 2 {
//            let real = forwardOutputReal[i]
//            let imag = forwardOutputImag[i]
//            let magnitude = sqrt(real * real + imag * imag)
//            output[i] = magnitude
//        }
//    }
//}
//
//// MARK: - 特征提取器
//
//class AudioFeatureExtractor: ObservableObject {
//    @Published var beatConfidences: [Double] = []
//    @Published var spectralConfidences: [Double] = []
//    @Published var harmonicConfidences: [Double] = []
//    @Published var combinedConfidences: [Double] = []
//    @Published var timeStamps: [Double] = [] // 时间标记
//    
//    private var engine = AVAudioEngine()
//    private var playerNode = AVAudioPlayerNode()
//    private var audioFile: AVAudioFile?
//    private let fftProcessor = FFTProcessor()
//    private var sampleRate: Double = 44100.0 // 默认采样率
//    
//    private let beatWeight: Double = 0.5
//    private let spectralWeight: Double = 0.3
//    private let harmonicWeight: Double = 0.2
//    
//    private var processingQueue = DispatchQueue(label: "audio.processing.queue", qos: .userInitiated)
//    private var isProcessing = false
//    private var processedFrameCount = 0
//    private var startTime: Date?
//    
//    /// 加载并处理音频
//    func loadAndProcessAudio(_ url: URL) {
//        reset()
//        isProcessing = true
//        startTime = Date()
//        
//        do {
//            audioFile = try AVAudioFile(forReading: url)
//            
//            // 获取实际采样率
//            sampleRate = audioFile?.fileFormat.sampleRate ?? 44100.0
//            
//            // 设置音频引擎
//            engine.attach(playerNode)
//            engine.connect(playerNode, to: engine.mainMixerNode, format: audioFile?.processingFormat)
//            
//            // 安装Tap获取音频数据
//            let format = engine.mainMixerNode.outputFormat(forBus: 0)
//            let bufferSize: AVAudioFrameCount = AVAudioFrameCount(FFTProcessor.windowSize * 2)
//            
//            engine.mainMixerNode.installTap(
//                onBus: 0,
//                bufferSize: bufferSize,
//                format: format
//            ) { [weak self] buffer, _ in
//                self?.processAudioBuffer(buffer)
//            }
//            
//            // 准备播放器
//            playerNode.scheduleFile(audioFile!, at: nil) { [weak self] in
//                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
//                    self?.isProcessing = false
//                    self?.finalizeProcessing()
//                }
//            }
//            
//            // 启动引擎
//            try engine.start()
//            playerNode.play()
//            
//        } catch {
//            print("Audio processing error: \(error)")
//            isProcessing = false
//        }
//    }
//    
//    /// 处理音频缓冲区
//    private func processAudioBuffer(_ buffer: AVAudioPCMBuffer) {
//        guard isProcessing else { return }
//        
//        processingQueue.async { [weak self] in
//            guard let self = self else { return }
//            
//            // 处理缓冲区
//            let spectrums = self.fftProcessor.process(buffer)
//            var beatResults: [Double] = []
//            var spectralResults: [Double] = []
//            var harmonicResults: [Double] = []
//            var combinedResults: [Double] = []
//            var timeResults: [Double] = [] // 时间标记
//            
//            // 计算每个频谱的时间点
//            let hopTime = Double(FFTProcessor.hopSize) / self.sampleRate
//            let startIndex = self.processedFrameCount
//            let totalFrames = self.processedFrameCount + spectrums.count
//            
//            for (index, spectrum) in spectrums.enumerated() {
//                // 计算时间点 (基于帧索引)
//                let timeStamp = Double(startIndex + index) * hopTime
//                timeResults.append(timeStamp)
//                
//                // 计算短时能量（节拍置信度）
//                let beatConfidence = self.calculateBeatConfidence(from: spectrum)
//                beatResults.append(beatConfidence)
//                
//                // 计算频谱质心
//                let spectralConfidence = self.calculateSpectralCentroid(from: spectrum)
//                spectralResults.append(spectralConfidence)
//                
//                // 计算谐波冲击度
//                let harmonicConfidence = self.calculateHarmonicContrast(from: spectrum)
//                harmonicResults.append(harmonicConfidence)
//                
//                // 融合特征
//                let combined = beatConfidence * self.beatWeight + 
//                               spectralConfidence * self.spectralWeight + 
//                               harmonicConfidence * self.harmonicWeight
//                combinedResults.append(combined)
//            }
//            
//            DispatchQueue.main.async {
//                self.beatConfidences.append(contentsOf: beatResults)
//                self.spectralConfidences.append(contentsOf: spectralResults)
//                self.harmonicConfidences.append(contentsOf: harmonicResults)
//                self.combinedConfidences.append(contentsOf: combinedResults)
//                self.timeStamps.append(contentsOf: timeResults)
//            }
//            
//            self.processedFrameCount += spectrums.count
//        }
//    }
//    
//    /// 完成处理
//    private func finalizeProcessing() {
//        processingQueue.async { [weak self] in
//            guard let self = self, !self.combinedConfidences.isEmpty else { return }
//            
//            // 应用移动平均平滑
//            let smoothKernel: [Double] = [0.1, 0.2, 0.4, 0.2, 0.1]
//            let smoothedCombined = self.applyConvolution(input: self.combinedConfidences, kernel: smoothKernel)
//            
//            DispatchQueue.main.async {
//                self.combinedConfidences = smoothedCombined
//            }
//        }
//    }
//    
//    /// 计算节拍置信度
//    private func calculateBeatConfidence(from spectrum: [Float]) -> Double {
//        // 计算总能量
//        var totalEnergy: Double = 0.0
//        var prevEnergy: Double = 0.0
//        var flux: Double = 0.0
//        
//        for i in 0..<spectrum.count {
//            let bin = Double(spectrum[i])
//            totalEnergy += bin
//            
//            if i > 0 {
//                flux += abs(bin - prevEnergy)
//            }
//            
//            prevEnergy = bin
//        }
//        
//        // 标准化
//        let normalizedFlux = flux / max(1, Double(spectrum.count))
//        let normalizedEnergy = totalEnergy / max(1, Double(spectrum.count))
//        
//        // 组合指标
//        let confidence = (normalizedFlux * 0.7) + (normalizedEnergy * 0.3)
//        return min(1.0, max(0.0, confidence))
//    }
//    
//    /// 计算频谱质心
//    private func calculateSpectralCentroid(from spectrum: [Float]) -> Double {
//        var sumWeighted = 0.0
//        var sum = 0.0
//        
//        for i in 0..<spectrum.count {
//            let bin = Double(spectrum[i])
//            let frequency = Double(i) / Double(spectrum.count)
//            
//            sumWeighted += bin * frequency
//            sum += bin
//        }
//        
//        let centroid = sum > 0 ? sumWeighted / sum : 0.0
//        // 将质心映射到0-1范围
//        return min(1.0, max(0.0, centroid * 1.5))
//    }
//    
//    /// 计算谐波冲击度
//    private func calculateHarmonicContrast(from spectrum: [Float]) -> Double {
//        // 分离谐波和打击乐成分
//        var harmonicPart: Double = 0.0
//        var percussivePart: Double = 0.0
//        
//        let binGroupSize = max(4, spectrum.count / 40)
//        
//        for groupStart in stride(from: 0, to: spectrum.count, by: binGroupSize) {
//            let groupEnd = min(groupStart + binGroupSize, spectrum.count)
//            var localMax: Double = 0.0
//            var groupSum: Double = 0.0
//            
//            for bin in groupStart..<groupEnd {
//                let value = Double(spectrum[bin])
//                groupSum += value
//                if value > localMax {
//                    localMax = value
//                }
//            }
//            
//            harmonicPart += groupSum
//            percussivePart += localMax
//        }
//        
//        // 计算谐波对比度
//        let contrast = harmonicPart > 0 ? percussivePart / harmonicPart : 0.0
//        return min(1.0, max(0.0, contrast * 0.8))
//    }
//    
//    /// 应用卷积平滑
//    private func applyConvolution(input: [Double], kernel: [Double]) -> [Double] {
//        let kernelSize = kernel.count
//        let halfKernelSize = kernelSize / 2
//        var output = [Double](repeating: 0, count: input.count)
//        
//        for i in 0..<input.count {
//            var convValue = 0.0
//            for j in 0..<kernelSize {
//                let idx = i + j - halfKernelSize
//                if idx >= 0 && idx < input.count {
//                    convValue += input[idx] * kernel[j]
//                }
//            }
//            output[i] = convValue
//        }
//        
//        return output
//    }
//    
//    /// 重置状态
//    private func reset() {
//        beatConfidences = []
//        spectralConfidences = []
//        harmonicConfidences = []
//        combinedConfidences = []
//        timeStamps = []
//        processedFrameCount = 0
//    }
//}
//
//// MARK: - 峰值检测器
//
//class PeakDetector: ObservableObject {
//    @Published var detectedPeaks: [Int] = []
//    @Published var peakTimes: [Double] = [] // 峰值对应的时间点
//    @Published var confidenceHistory: [Double] = []
//    
//    private let minPeakHeight: Double = 0.5
//    private let minPeakDistance: Int = 5 // 最小峰值距离（单位：帧）
//    
//    /// 在数据中检测峰值
//    func detectPeaks(in confidenceData: [Double], timeStamps: [Double]) {
//        DispatchQueue.global(qos: .userInitiated).async { [weak self] in
//            guard let self = self else { return }
//            
//            self.confidenceHistory = confidenceData
//            
//            var peaks: [Int] = []
//            var peakTimes: [Double] = [] // 存储峰值对应的时间
//            let data = confidenceData
//            
//            // 如果数据点太少，直接返回
//            if data.count < 2 {
//                DispatchQueue.main.async {
//                    self.detectedPeaks = []
//                    self.peakTimes = []
//                }
//                return
//            }
//            
//            // 滑动窗口峰值检测算法
//            let windowSize = minPeakDistance
//            for i in 0..<data.count {
//                // 跳过边界点
//                if i < windowSize || i >= data.count - windowSize {
//                    continue
//                }
//                
//                // 检查高度条件
//                guard data[i] > self.minPeakHeight else { continue }
//                
//                // 检查局部最大值条件
//                var isPeak = true
//                let leftStart = max(0, i - windowSize)
//                let rightEnd = min(data.count - 1, i + windowSize)
//                
//                for j in leftStart...rightEnd {
//                    if i != j && data[j] > data[i] {
//                        isPeak = false
//                        break
//                    }
//                }
//                
//                // 检查最小距离条件
//                if isPeak {
//                    if let lastPeak = peaks.last, i - lastPeak < self.minPeakDistance {
//                        // 保留更高的峰值
//                        if data[i] > data[lastPeak] {
//                            peaks[peaks.count - 1] = i
//                            peakTimes[peakTimes.count - 1] = timeStamps[i]
//                        }
//                    } else {
//                        peaks.append(i)
//                        peakTimes.append(timeStamps[i])
//                    }
//                }
//            }
//            
//            DispatchQueue.main.async {
//                self.detectedPeaks = peaks
//                self.peakTimes = peakTimes
//            }
//        }
//    }
//    
//    /// 波段缩放功能
//    func scaleToFrequencyBand(confidenceData: [Double], timeStamps: [Double], startTime: Double, endTime: Double) -> ([Double], [Double]) {
//        guard !confidenceData.isEmpty, !timeStamps.isEmpty else {
//            return ([], [])
//        }
//        
//        // 查找时间范围内的数据点
//        var scaledData: [Double] = []
//        var scaledTimes: [Double] = []
//        
//        for (index, time) in timeStamps.enumerated() {
//            if time >= startTime && time <= endTime {
//                scaledData.append(confidenceData[index])
//                scaledTimes.append(time)
//            }
//        }
//        
//        return (scaledData, scaledTimes)
//    }
//}
//
//// MARK: - 可视化视图
//
//struct MultiFeatureBeatVisualizer: View {
//    @StateObject private var featureExtractor = AudioFeatureExtractor()
//    @StateObject private var peakDetector = PeakDetector()
//    @State private var audioURL: URL?
//    @State private var isProcessing = false
//    @State private var processingProgress: Double = 0.0
//    @State private var startTime: Double = 0.0
//    @State private var endTime: Double = 10.0
//    @State private var selectedBand: FrequencyBand = .all
//    
//    // 波段选择
//    enum FrequencyBand: String, CaseIterable, Identifiable {
//        case all = "全部"
//        case low = "低频"
//        case mid = "中频"
//        case high = "高频"
//        
//        var id: String { self.rawValue }
//    }
//    
//    // 可视化参数
//    private let barWidth: CGFloat = 2.0
//    private let barSpacing: CGFloat = 1.0
//    private let waveHeight: CGFloat = 200
//    
//    var body: some View {
//        VStack(spacing: 20) {
//            // 标题和控制区域
//            VStack(spacing: 10) {
//                Text("多特征融合卡点分析")
//                    .font(.title)
//                    .fontWeight(.bold)
//                
//                HStack(spacing: 20) {
//                    Button(action: selectAudioFile) {
//                        HStack {
//                            Image(systemName: "waveform.path")
//                            Text("选择音频")
//                        }
//                        .padding(10)
//                        .background(Color.blue)
//                        .foregroundColor(.white)
//                        .cornerRadius(10)
//                    }
//                    
//                    if isProcessing {
//                        ProgressView(value: processingProgress)
//                            .progressViewStyle(LinearProgressViewStyle(tint: .blue))
//                            .frame(width: 200)
//                    }
//                    
//                    // 波段选择器
//                    if !featureExtractor.combinedConfidences.isEmpty {
//                        Picker("频率波段", selection: $selectedBand) {
//                            ForEach(FrequencyBand.allCases) { band in
//                                Text(band.rawValue).tag(band)
//                            }
//                        }
//                        .pickerStyle(SegmentedPickerStyle())
//                        .frame(width: 200)
//                    }
//                }
//                
//                if !featureExtractor.combinedConfidences.isEmpty {
//                    Text("检测到 \(peakDetector.detectedPeaks.count) 个卡点位置")
//                        .font(.headline)
//                }
//            }
//            .padding()
//            
//            // 波形可视化
//            GeometryReader { geometry in
//                VStack(spacing: 10) {
//                    // 时间轴控件
//                    if !featureExtractor.timeStamps.isEmpty {
////                        let maxTime = featureExtractor.timeStamps.last ?? 10
//                        let maxTime = max(0.1, featureExtractor.timeStamps.last ?? 10)
//                        let safeMaxTime = max(maxTime, endTime)
//                        
//                        VStack {
//                            // 开始时间滑块
//                            HStack {
//                                Text("开始时间: \(startTime, specifier: "%.1f")s")
//                                    .font(.caption)
//                                    .frame(width: 80)
//                                
//                                Slider(value: $startTime, in: 0...safeMaxTime, step: 0.1) {
//                                    Text("开始时间")
//                                }
//                                .frame(height: 20)
//                            }
//                            
//                            // 结束时间滑块
//                            HStack {
//                                Text("结束时间: \(endTime, specifier: "%.1f")s")
//                                    .font(.caption)
//                                    .frame(width: 80)
//                                
//                                Slider(value: $endTime, in: startTime...safeMaxTime, step: 0.1) {
//                                    Text("结束时间")
//                                }
//                                .frame(height: 20)
//                            }
//                        }
//                        .padding(.horizontal)
//                    }
//                    
//                    // 特征叠加图
//                    ZStack {
//                        // 背景网格
//                        Path { path in
//                            for i in 0...10 {
//                                let y = CGFloat(i) * (waveHeight / 10)
//                                path.move(to: CGPoint(x: 0, y: y))
//                                path.addLine(to: CGPoint(x: geometry.size.width, y: y))
//                            }
//                        }
//                        .stroke(Color.gray.opacity(0.2), lineWidth: 0.5)
//                        
//                        // 时间标记
//                        if !featureExtractor.timeStamps.isEmpty {
//                            let maxTime = featureExtractor.timeStamps.last ?? 1
//                            let timeInterval = max(1.0, maxTime / 5) // 确保时间间隔至少为1秒
//                            
//                            ForEach(0..<6, id: \.self) { i in
//                                let time = Double(i) * timeInterval
//                                
//                                // 只显示在可见范围内的标记
//                                if time >= startTime && time <= endTime {
//                                    let x = positionForTime(time, in: geometry.size.width)
//                                    
//                                    Path { path in
//                                        path.move(to: CGPoint(x: x, y: 0))
//                                        path.addLine(to: CGPoint(x: x, y: waveHeight))
//                                    }
//                                    .stroke(Color.gray.opacity(0.3), lineWidth: 0.5)
//                                    
//                                    Text("\(time, specifier: "%.1f")s")
//                                        .font(.caption)
//                                        .position(x: x, y: waveHeight + 15)
//                                }
//                            }
//                        }
//                        
//                        // 节拍置信度
//                        confidencePath(values: scaledBeatConfidences, color: .red, height: waveHeight, width: geometry.size.width)
//                        
//                        // 频谱质心
//                        confidencePath(values: scaledSpectralConfidences, color: .green, height: waveHeight, width: geometry.size.width)
//                        
//                        // 谐波冲击度
//                        confidencePath(values: scaledHarmonicConfidences, color: .blue, height: waveHeight, width: geometry.size.width)
//                        
//                        // 融合置信度
//                        confidencePath(values: scaledCombinedConfidences, color: .purple, height: waveHeight, width: geometry.size.width)
//                        
//                        // 检测到的峰值
//                        ForEach(0..<peakDetector.detectedPeaks.count, id: \.self) { idx in
//                            let index = peakDetector.detectedPeaks[idx]
//                            let time = peakDetector.peakTimes[idx]
//                            
//                            if isInTimeRange(time) {
//                                let position = positionForTime(time, in: geometry.size.width)
//                                let confidence = scaledCombinedConfidences[index]
//                                let y = waveHeight - CGFloat(confidence) * waveHeight
//                                
//                                VStack(spacing: 2) {
//                                    Circle()
//                                        .fill(Color.yellow)
//                                        .frame(width: 12, height: 12)
//                                        .overlay(
//                                            Circle()
//                                                .stroke(Color.white, lineWidth: 2)
//                                        )
//                                        .shadow(color: .yellow, radius: 5)
//                                    
//                                    Text("\(time, specifier: "%.2f")s")
//                                        .font(.system(size: 10))
//                                        .padding(2)
//                                        .background(Color.black.opacity(0.5))
//                                        .cornerRadius(3)
//                                        .foregroundColor(.white)
//                                }
//                                .position(x: position, y: y - 20)
//                            }
//                        }
//                    }
//                    .frame(height: waveHeight)
//                    .background(Color.black.opacity(0.1))
//                    .cornerRadius(8)
//                    
//                    // 特征图例
//                    HStack {
//                        HStack {
//                            Rectangle()
//                                .fill(Color.red)
//                                .frame(width: 15, height: 3)
//                            Text("节拍强度")
//                                .font(.caption)
//                        }
//                        HStack {
//                            Rectangle()
//                                .fill(Color.green)
//                                .frame(width: 15, height: 3)
//                            Text("频谱质心")
//                                .font(.caption)
//                        }
//                        HStack {
//                            Rectangle()
//                                .fill(Color.blue)
//                                .frame(width: 15, height: 3)
//                            Text("谐波冲击")
//                                .font(.caption)
//                        }
//                        HStack {
//                            Rectangle()
//                                .fill(Color.purple)
//                                .frame(width: 15, height: 3)
//                            Text("融合特征")
//                                .font(.caption)
//                        }
//                    }
//                    .padding(.vertical, 5)
//                }
//                .padding(.horizontal, 10)
//            }
//            .padding(.horizontal, 20)
//            
//            // 详细特征展示
//            if !featureExtractor.combinedConfidences.isEmpty {
//                HStack(spacing: 0) {
//                    DetailFeatureChart(
//                        title: "节拍强度",
//                        data: scaledBeatConfidences,
//                        color: .red,
//                        min: 0,
//                        max: 1.0
//                    )
//                    
//                    DetailFeatureChart(
//                        title: "频谱质心",
//                        data: scaledSpectralConfidences,
//                        color: .green,
//                        min: 0,
//                        max: 1.0
//                    )
//                    
//                    DetailFeatureChart(
//                        title: "谐波冲击",
//                        data: scaledHarmonicConfidences,
//                        color: .blue,
//                        min: 0,
//                        max: 1.0
//                    )
//                }
//                .frame(height: 150)
//                .padding(.horizontal, 20)
//            }
//            
//            Spacer()
//        }
//        .onChange(of: featureExtractor.combinedConfidences) { newValue in
//            if !newValue.isEmpty {
//                peakDetector.detectPeaks(in: newValue, timeStamps: featureExtractor.timeStamps)
//                isProcessing = false
//                
//                // 设置初始时间范围
//                if let maxTime = featureExtractor.timeStamps.last {
//                    endTime = min(10.0, maxTime) // 初始显示前10秒
//                }
//            }
//        }
//        .onChange(of: startTime) { _ in
//            // 确保开始时间不超过结束时间
//            if startTime > endTime {
//                endTime = startTime
//            }
//        }
//        .onChange(of: endTime) { _ in
//            // 确保结束时间不小于开始时间
//            if endTime < startTime {
//                startTime = endTime
//            }
//        }
//        .onChange(of: selectedBand) { _ in
//            // 波段变化时更新视图
//        }
//        .onAppear {
//            // 开发测试时自动加载示例
//            #if DEBUG
//            if let demoURL = Bundle.main.url(forResource: "GG", withExtension: "wav") {
//                processAudio(url: demoURL)
//            }
//            #endif
//        }
//    }
//    
//    // 波段缩放后的特征数据
//    private var scaledBeatConfidences: [Double] {
//        applyBandScaling(featureExtractor.beatConfidences)
//    }
//    
//    private var scaledSpectralConfidences: [Double] {
//        applyBandScaling(featureExtractor.spectralConfidences)
//    }
//    
//    private var scaledHarmonicConfidences: [Double] {
//        applyBandScaling(featureExtractor.harmonicConfidences)
//    }
//    
//    private var scaledCombinedConfidences: [Double] {
//        applyBandScaling(featureExtractor.combinedConfidences)
//    }
//    
//    /// 应用波段缩放
//    private func applyBandScaling(_ data: [Double]) -> [Double] {
//        guard !data.isEmpty else { return [] }
//        
//        // 根据选择的波段缩放数据
//        switch selectedBand {
//        case .low:
//            return data.map { $0 * 0.8 }
//        case .mid:
//            return data.map { $0 * 1.2 }
//        case .high:
//            return data.map { $0 * 1.5 }
//        case .all:
//            return data
//        }
//    }
//    
//    /// 检查时间点是否在选定范围内
//    private func isInTimeRange(_ time: Double) -> Bool {
//        time >= startTime && time <= endTime
//    }
//    
//    /// 根据时间计算位置
//    private func positionForTime(_ time: Double, in width: CGFloat) -> CGFloat {
//        guard endTime > startTime else { return 0 }
//        
//        let normalizedTime = (time - startTime) / (endTime - startTime)
//        return CGFloat(normalizedTime) * width
//    }
//    
//    /// 创建置信度路径
//    private func confidencePath(values: [Double], color: Color, height: CGFloat, width: CGFloat) -> some View {
//        Path { path in
//            guard !values.isEmpty else { return }
//            
//            let stepX = width / CGFloat(values.count)
//            
//            // 移动到第一个点
//            let startConfidence = max(0.0, min(1.0, CGFloat(values[0])))
//            let startY = height - startConfidence * height
//            path.move(to: CGPoint(x: 0, y: startY))
//            
//            // 连接后续点
//            for i in 1..<values.count {
//                let confidence = max(0.0, min(1.0, CGFloat(values[i])))
//                let y = height - confidence * height
//                let x = CGFloat(i) * stepX
//                path.addLine(to: CGPoint(x: x, y: y))
//            }
//        }
//        .stroke(color, style: StrokeStyle(lineWidth: 1.5, lineCap: .round, lineJoin: .round))
//    }
//    
//    /// 选择音频文件
//    private func selectAudioFile() {
//        #if os(macOS)
//        openFilePanel()
//        #else
//        // 在iOS上，需要实现一个真正的文件选择器
//        // 这里使用测试音频代替
//        if let testURL = Bundle.main.url(forResource: "GG", withExtension: "wav") {
//            processAudio(url: testURL)
//        }
//        #endif
//    }
//    
//    #if os(macOS)
//    /// macOS文件选择器
//    private func openFilePanel() {
//        let panel = NSOpenPanel()
//        panel.allowedContentTypes = [.audio]
//        panel.allowsMultipleSelection = false
//        
//        if panel.runModal() == .OK, let url = panel.url {
//            processAudio(url: url)
//        }
//    }
//    #endif
//    
//    /// 处理音频
//    private func processAudio(url: URL) {
//        isProcessing = true
//        processingProgress = 0.0
//        audioURL = url
//        startTime = 0.0
//        endTime = 10.0
//        featureExtractor.loadAndProcessAudio(url)
//        
//        // 模拟处理进度
//        Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { timer in
//            if processingProgress >= 1.0 {
//                timer.invalidate()
//            } else {
//                withAnimation {
//                    processingProgress = min(1.0, processingProgress + 0.01)
//                }
//            }
//        }
//    }
//}
//
//// MARK: - 详细特征图表
//
//struct DetailFeatureChart: View {
//    let title: String
//    let data: [Double]
//    let color: Color
//    let min: Double
//    let max: Double
//    
//    var body: some View {
//        GeometryReader { geometry in
//            ZStack(alignment: .topLeading) {
//                // 背景网格
//                Path { path in
//                    for i in 0..<5 {
//                        let y = geometry.size.height * CGFloat(i) / 4
//                        path.move(to: CGPoint(x: 0, y: y))
//                        path.addLine(to: CGPoint(x: geometry.size.width, y: y))
//                    }
//                }
//                .stroke(Color.gray.opacity(0.2), lineWidth: 1)
//                
//                // 数据路径
//                Path { path in
//                    guard !data.isEmpty else { return }
//                    
//                    let height = geometry.size.height
//                    let width = geometry.size.width
//                    let stepX = width / CGFloat(data.count)
//                    
//                    let normalized = normalizedValue(for: data[0])
//                    let startY = height - normalized * height
//                    path.move(to: CGPoint(x: 0, y: startY))
//                    
//                    for i in 1..<data.count {
//                        let x = CGFloat(i) * stepX
//                        let normalized = normalizedValue(for: data[i])
//                        let y = height - normalized * height
//                        path.addLine(to: CGPoint(x: x, y: y))
//                    }
//                }
//                .stroke(color, lineWidth: 2)
//                
//                // 区域填充
//                Path { path in
//                    guard !data.isEmpty else { return }
//                    
//                    let height = geometry.size.height
//                    let width = geometry.size.width
//                    let stepX = width / CGFloat(data.count)
//                    
//                    path.move(to: CGPoint(x: 0, y: height))
//                    
//                    for i in 0..<data.count {
//                        let x = CGFloat(i) * stepX
//                        let normalized = normalizedValue(for: data[i])
//                        let y = height - normalized * height
//                        path.addLine(to: CGPoint(x: x, y: y))
//                    }
//                    
//                    path.addLine(to: CGPoint(x: width, y: height))
//                    path.closeSubpath()
//                }
//                .fill(color.opacity(0.2))
//                
//                // 标题
//                Text(title)
//                    .font(.caption)
//                    .fontWeight(.bold)
//                    .foregroundColor(color)
//                    .padding(3)
//                    .background(RoundedRectangle(cornerRadius: 3).fill(Color.white.opacity(0.7)))
//                    .offset(x: 5, y: 5)
//            }
//        }
//        .padding(3)
//    }
//    
//    private func normalizedValue(for value: Double) -> CGFloat {
//        let range = max - min
//        let normalized = (value - min) / range
//        return CGFloat(normalized)
//    }
//}
//
//// MARK: - 应用主入口
//
////@main
////struct MultiFeatureBeatAnalyzerApp: App {
////    var body: some Scene {
////        WindowGroup {
////            MultiFeatureBeatVisualizer()
////                .frame(minWidth: 800, minHeight: 600)
////        }
////    }
////}
